﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Windows.Threading;

using ProtoImaginer.Models;
using ProtoImaginer.ProtoControl;
using ProtoImaginer.ProtoPage;

namespace ProtoImaginer.ProtoDemo
{
    public partial class ProjectDemo : PhoneApplicationPage
    {
        private Models.Page page;
        private Models.Image image;
        private ControlAtom tapedControl;
        private const string strConnectionString = @"isostore:/protoDataContext.sdf";


        public ProjectDemo()
        {
            InitializeComponent();
            TitleFadeOut.Begin();
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            page = Models.ProtoDataContext.LoadPageByPK(NavigationContext.QueryString["pageId"]);
            image = Models.ProtoDataContext.LoadImagesByPageId(page.PageId);
            UpdatePage();
        } 

        #region UI handler

        private void CanvasPinchStarted(object sender, PinchStartedGestureEventArgs e){}

        private void CanvasPinchDelta(object sender, PinchGestureEventArgs e)
        {
            if (e.DistanceRatio < 1)
            {
                var finger1 = e.GetPosition(DemoCanvas, 0);
                var finger2 = e.GetPosition(DemoCanvas, 1);

                DemoCanvas.RenderTransformOrigin = new Point(
                (finger2.X + finger1.X) / 2 / DemoCanvas.ActualWidth,
                (finger2.Y + finger1.Y) / 2 / DemoCanvas.ActualHeight);

                var transform = (CompositeTransform)DemoCanvas.RenderTransform;
                transform.ScaleX *= Math.Sqrt(e.DistanceRatio);
                transform.ScaleY = transform.ScaleX;
            }
        }

        private void CanvasPinchCompleted(object sender, PinchGestureEventArgs e)
        {
            var transform = (CompositeTransform)DemoCanvas.RenderTransform;
            if(transform.ScaleX < 0.8)
                NavigationService.GoBack();
            else
            {
                transform.ScaleX = 1;
                transform.ScaleY = 1;
            }
        }

        private void CanvasTap(object sender, GestureEventArgs e)
        {
            if (!e.Handled) {
                FlashEffect.Stop();
                FlashEffect.SetValue(Storyboard.TargetNameProperty, ControlContainer.Name);

                foreach (ControlAtom control in ControlContainer.Children)
                    control.Opacity = 1;
                FlashEffect.Begin();
                FlashEffect.Completed += AfterWholeFlash;

            }
        }

        private void ControlAtomTap(object sender, GestureEventArgs e)
        {
            e.Handled = true;
            //TODO UI animation jump to next page
            FlashEffect.Stop();

            tapedControl = (ControlAtom)sender;

            Storyboard.SetTarget(FlashEffect, tapedControl);

            FlashEffect.Begin();
            ImageFadeOut.Begin();
            FlashEffect.Completed += UpdatePage;
        }

        #endregion

        #region UI misc
        
        private void AfterWholeFlash(object sender, EventArgs e)
        {
            foreach (ControlAtom control in ControlContainer.Children)
                control.Opacity = 0;
            FlashEffect.Completed -= AfterWholeFlash;
        }


        //this method will be called to update the page after a control is clicked and finish flashing.
        private void UpdatePage(object sender, EventArgs e)
        {
            //TODO get page according to control
            if (tapedControl.IsLinked())
            {
                image = Models.ProtoDataContext.LoadImageByPK(tapedControl.GetlinkToImageId());
                var temp = Models.ProtoDataContext.LoadPageByPK(image.PageId);
            }
            UpdatePage();
            FlashEffect.Completed -= UpdatePage;
        }

        private void BindControlItemListener(ControlAtom newItem)
        {
            GestureListener listener = GestureService.GetGestureListener(newItem);
            listener.Tap += ControlAtomTap;
        }

        #endregion

        #region data related operation

        private void UpdatePage(){

            //TODO get imageId according to PageId
            ControlContainer.Children.Clear();
            var controlData = Models.ProtoDataContext.LoadControlsByImageId(image.ImageId);
            foreach (Models.Control control in controlData) {
                AddControl(control);
            }
            //update UI
            BitmapImage img = new BitmapImage();
            if (image.ImageId != MainPage.tempImg.ImageId || PageView.tempImg == null)
                img.SetSource(Application.GetResourceStream(new Uri(@image.ImageSource, UriKind.Relative)).Stream);
            else
                img = PageView.tempImg;
            Image.Source = img;
            ImageFadeIn.Begin();
        }

        //add control
        private void AddControl(Models.Control control)
        {
            //initialize new control item.
            ControlAtom newItem = new ControlAtom(control);
            newItem.Opacity = 0;
            try
            {
                //UI related
                ControlContainer.Children.Add(newItem);
                newItem.Name = "Control-" + (int)control.Control_Top_Left_Point_X_Coordinate + "-" + (int)control.Control_Top_Left_Point_Y_Coordinate;
                
                //bind listeners
                BindControlItemListener(newItem);

            }
            catch (Exception)
            {
                MessageBox.Show("Unable to load control.");
            }

        }
        #endregion
    }
}